﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Xml.Serialization;
using System.IO;

namespace Mimoza.PuttyPlugin
{
    public class RegistryData
    {   
        public string          KeyName;
        public RegistryValue[] Values;   
    }

    public class RegistryValue
    {
        public string               Name;
        public RegistryValueKind    Kind;

        public string               Value; // string representation
    }

    class RegistrySettings
    {
        public RegistrySettings()
        {
        }

        public RegistrySettings(string keyPath)
        {
            Init(keyPath);
        }

        public void Init(string keyPath)
        {
            Common.Logger.Log.Info("RegistrySettings.Init keyPath - {0}.", keyPath);

            m_key = Registry.LocalMachine.OpenSubKey(keyPath, true);
            if (m_key == null)
            {
                m_key = Registry.LocalMachine.CreateSubKey(keyPath);
                if (m_key == null)
                {
                    Common.Logger.Log.Error("SettingsRegistry.Init can't create applicaion key.");
                    return;
                }

            }

            m_keyPath = keyPath;
        }

        public void ApplyFromBinary(string binaryStr)
        {
            RegistryData regData = Deserialize(binaryStr);

            if (m_key == null) Init(regData.KeyName);
            
            if (m_key == null) throw new ArgumentNullException();

            foreach(RegistryValue value in regData.Values)
            {
                switch(value.Kind)
                {
                    case RegistryValueKind.DWord:
                        long lVal;
                        lVal = long.Parse(value.Value);

                        m_key.SetValue(value.Name, lVal, value.Kind);
 
                        break;
                    case RegistryValueKind.String:

                        m_key.SetValue(value.Name, value.Value, value.Kind);
                        
                        break;
                    default:
                        break;
                }
            }
        }

        public void EraseFrom(string binaryStr)
        {
            RegistryData regData = Deserialize(binaryStr);

            Common.Logger.Log.Info("RegistrySettings.EraseFrom keyPath - {0}.", regData.KeyName);

            Registry.LocalMachine.DeleteSubKeyTree(regData.KeyName);
        }

        public void SaveToFile(string fileName)
        {
            if (m_key==null) throw new ArgumentNullException();

            List<RegistryValue> values = new List<RegistryValue>(); 
            foreach (string name in m_key.GetValueNames())
            {
                RegistryValue value = new RegistryValue();
                value.Name = name;
                value.Value = m_key.GetValue(name).ToString();
                value.Kind = m_key.GetValueKind(name);

                values.Add(value);
            }

            RegistryData regData = new RegistryData();
            regData.KeyName = m_keyPath;
            regData.Values = values.ToArray();

            XmlSerializer serializer = new XmlSerializer(typeof(RegistryData));
            using(FileStream fs = File.Open(fileName, FileMode.Create))
            {
                serializer.Serialize(fs, regData);
            }
        }

        private static RegistryData Deserialize(string binaryStr)
        {
            RegistryData regData = null;
            XmlSerializer deserializer = new XmlSerializer(typeof(RegistryData));
            using (TextReader text = new StringReader(binaryStr))
            {
                regData = deserializer.Deserialize(text) as RegistryData;
            }
            return regData;
        }

        RegistryKey m_key;
        string      m_keyPath;
    }
}
